﻿using Engine;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Game.Server;
using Game.Server.Plugins;
using System.Globalization;
using Game.NetWork;
using LiteNetLib;
using Game.NetWork.Packages;

namespace Game
{
    public class CmdPersonalCode : AbstractProcessCmd
    {
        public override string Cmd => "setpc";

        public override string Introduce => "/setpc  -查看个人房间密码指令";

        public override int AuthLevel => 1000;

        public override DisplayType Display => DisplayType.Authority;

        public override void ProcessCmd()
        {
            if (GameManager.Project == null)
            {
                SendMessage(Cmd, "请先进入存档");
                return;
            }
            if (m_messageDatas.Length >= 2)
            {
                if (m_messageDatas[1] == "add" && m_messageDatas.Length == 4)
                {
                    string name = m_messageDatas[2];
                    string paw = m_messageDatas[3];
                    PersonalCodePlugin.PersonalCodeList[paw] = name;
                    SendMessage(Cmd, "个人密码添加成功:" + name);
                }
                else if(m_messageDatas[1] == "rem" && m_messageDatas.Length == 3)
                {
                    string name = m_messageDatas[2];
                    List<string> toRemove = new List<string>();
                    foreach(var item in PersonalCodePlugin.PersonalCodeList)
                    {
                        if(name == item.Value)
                        {
                            toRemove.Add(item.Key);
                        }
                    }
                    foreach (string s in toRemove)
                    {
                        PersonalCodePlugin.PersonalCodeList.Remove(s);
                    }
                    SendMessage(Cmd, "个人密码移除成功:" + name);
                }
                else if(m_messageDatas[1] == "show" && m_messageDatas.Length == 2)
                {
                    string msg = "";
                    foreach (var item in PersonalCodePlugin.PersonalCodeList)
                    {
                        msg += $"名称:{item.Value} 密码:{item.Key}\n";
                    }
                    SendMessage(Cmd, msg);
                }
                else
                {
                    SendMessage(Cmd, "输入的指令有误，请检查");
                }
            }
            else
            {
                string help = @"
    /setpc add name paw     -添加指定玩家,name为玩家名称,paw为密码
    /setpc rem name         -移除指定玩家,name为玩家名称
    /setpc show             -展示全部名单";
                SendMessage(Cmd, help);
            }
        }
    }
    
    public class PersonalCodePlugin : ServerPlugin, IBanEventHandle
    {

        public static Dictionary<string, string> PersonalCodeList = new Dictionary<string, string>();

        public override string Name => "个人进服密码插件";

        public override int Version => 10000;

        public byte FirstLevel => 0;

        public static string PersonalCodePath;

        public override void Initialize()
        {
            BanEventManager.AddObject(this);
        }

        public string GetPluginDataByWorldPath(string fileName)
        {
            string pluginDataPath = Storage.GetSystemPath("app:/PluginData");
            if (!Directory.Exists(pluginDataPath))
            {
                Directory.CreateDirectory(pluginDataPath);
            }
            string worldName = GameManager.Project.FindSubsystem<SubsystemGameInfo>().WorldSettings.Name;
            string dataByWorldPath = Storage.CombinePaths(pluginDataPath, worldName);
            if (!Directory.Exists(dataByWorldPath))
            {
                Directory.CreateDirectory(dataByWorldPath);
            }
            return Storage.CombinePaths(dataByWorldPath, fileName);
        }

        public override void Load()
        {
            PersonalCodePath = GetPluginDataByWorldPath("PersonalCode.json"); 
            try
            {
                PersonalCodeList.Clear();
                if (File.Exists(PersonalCodePath))
                {
                    using (StreamReader file = File.OpenText(PersonalCodePath))
                    {
                        string jsonText = file.ReadToEnd();
                        PersonalCodeList = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonText);
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error($"插件{Name}装载失败：{e.Message}");
            }
        }

        public override void Save()
        {
            try
            {
                string jsonText = JsonConvert.SerializeObject(PersonalCodeList);
                using (FileStream fileStream = File.Open(PersonalCodePath, FileMode.Create))
                {
                    using (StreamWriter fileWrite = new StreamWriter(fileStream))
                    {
                        fileWrite.Write(jsonText);
                        fileWrite.Flush();
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error($"插件{Name}保存失败：{e.Message}");
            }
        }

        public bool IsBanIp(string ip, NetNode netNode, ConnectionRequest request)
        {
            return false;
        }

        public bool IsBan(string nickname, string id, string password, string ip, NetNode netNode, Client client, out bool UseExternalPassword)
        {
            UseExternalPassword = true;
            if (!string.IsNullOrEmpty(password) && !string.IsNullOrEmpty(nickname))
            {
                if (PersonalCodeList.TryGetValue(password, out string Name))
                {
                    if(nickname == Name)
                    {
                        return false;
                    }
                }
            }
            netNode.SendWriterFromPackage(new ConnectionRejectPackage("房间个人密码错误"), client.Request, true);
            return true;
        }
    }
}